package com.leo.biz.service.aop;

import com.leo.biz.service.cache.RedisUtil;
import com.leo.biz.service.impl.Alog;

import com.leo.biz.service.msgcenter.MsgSendService;
import com.leo.biz.service.pub.CommUtil;
import org.apache.log4j.spi.LoggerFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Map;

/**
 * Created by leo on 2016/9/14.
 */

@Aspect
@Service
public class UserTracer {

    private static  String MAX_COST_TIME="MAX_COST_TIME";
    private static  String AVG_COST_TIME="AVG_COST_TIME";
    private static  String MIN_COST_TIME="MIN_COST_TIME";
    private static  String REQUEST_COUNT="REQ_COUNT_1";

    @Autowired
    private MsgSendService msgSendService;

    @Pointcut("execution(* com.leo.biz.controller.*.*(..))")
    public void pointCut()
    {

    }


    static Logger alog = org.slf4j.LoggerFactory.getLogger(UserTracer.class);


    @AfterReturning(pointcut="pointCut()",returning="ret")
    public void afterLog(JoinPoint joinPoint,Object ret) {
        if(joinPoint==null || joinPoint.getSignature()==null ||joinPoint.getSignature().getName()==null)
        {
            return;
        }
        HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        long beg=Long.valueOf(request.getSession().getAttribute("Beg_Time").toString());
        long end=System.currentTimeMillis();
        String url= request.getRequestURL().toString();
        if(!url.contains("test/dotest"))
        {
            alog.info("Method End:[" + joinPoint.getSignature().getName() + "],Ret:" + ret.toString()+" cost:"+(end-beg)+"ms");
            return;
        }

        if(!RedisUtil.exsit("MAX_COST_TIME"))
        {
            RedisUtil.putKey("MAX_COST_TIME",end-beg);
        }else
        {
            Long maxCostTime=Long.valueOf(RedisUtil.getKey("MAX_COST_TIME").toString());
            if((end-beg)>maxCostTime)
            {
                RedisUtil.putKey("MAX_COST_TIME",end-beg);
            }
        }

        Map map = Collections.singletonMap("key", "Value");



        RedisUtil.incr(REQUEST_COUNT);


        if(!RedisUtil.exsit(MIN_COST_TIME))
        {
            RedisUtil.putKey(MIN_COST_TIME,end-beg);
        }else
        {
            Long maxCostTime=Long.valueOf(RedisUtil.getKey(MIN_COST_TIME).toString());
            if((end-beg)<maxCostTime)
            {
                RedisUtil.putKey(MIN_COST_TIME,end-beg);
            }
        }


        if(!RedisUtil.exsit(AVG_COST_TIME))
        {
            RedisUtil.putKey(AVG_COST_TIME,end-beg);
        }else
        {
            long avg=Long.valueOf(RedisUtil.getKey(AVG_COST_TIME).toString());
            long count=Long.valueOf(RedisUtil.getKey(REQUEST_COUNT).toString());
            long new_avg=(avg*(count-1)+end-beg)/(count);
            RedisUtil.putKey(AVG_COST_TIME,new_avg);
        }



        alog.info("Method End:[" + joinPoint.getSignature().getName() + "],Ret:" + (ret!=null?ret.toString():"void")+" cost:"+(end-beg)+"ms");
        msgSendService.send("user_trace","",  CommUtil.getCurDate()+" | "+url+" | Method End:[" + joinPoint.getSignature().getName() + "],Ret:" + (ret!=null?ret.toString():"void")+" cost:"+(end-beg)+"ms");


    }

    @Before("pointCut()")
    public void beforeLog(JoinPoint joinPoint) {

        HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String url= request.getRequestURL().toString();

        String argsStr="";
        for (int i = 0; i < joinPoint.getArgs().length; i++) {


            argsStr=argsStr+(joinPoint.getArgs()[i].toString())+"   ";
        }
        alog.info("Request URL:" + url);
        String classType = joinPoint.getTarget().getClass().getName();
        Class<?> clazz = null;
        try {
            clazz = Class.forName(classType);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        String clazzName = clazz.getName();
        request.getSession().setAttribute("Beg_Time",System.currentTimeMillis());



        alog.info("Method Begin:[" + clazzName + "." + joinPoint.getSignature().getName() + "] Args:" + argsStr);



    }



}
